package edu.upc.fib.lamsandroid.server.lams.manager;

import edu.upc.fib.lamsandroid.server.manager.UserManager;
import edu.upc.fib.lamsandroid.server.lams.mapper.*;
import edu.upc.fib.lamsandroid.server.lams.model.*;
import edu.upc.fib.lamsandroid.server.api.model.Group;
import edu.upc.fib.lamsandroid.server.api.model.Organisation;
import edu.upc.fib.lamsandroid.server.api.model.User;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: TXABI
 * Date: 22/03/13
 * Time: 22:14
 * To change this template use File | Settings | File Templates.
 */

@Service
public class UserManagerImpl implements UserManager {

    @Autowired
    private LamsUserMapper userMapper;

    @Autowired
    private LamsUserGroupMapper userGroupMapper;

    @Autowired
    private LamsUserOrganisationMapper userOrganisationMapper;

    @Autowired
    private LamsGroupMapper groupMapper;

    @Autowired
    private LamsOrganisationMapper organisationMapper;



    @Override
    public User fetchById(Long id) {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public List<User> fetchAll() {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public boolean completeByCredentials(User user) {
        LamsUserExample userExample = new LamsUserExample();
        userExample.createCriteria()
                .andLoginEqualTo(user.getUsername())
                .andPasswordEqualTo(DigestUtils.sha1Hex(user.getPassword()));

        List<LamsUser> result = userMapper.selectByExample(userExample);

        if(result.size() == 1) {
            LamsUser lamsUser = result.get(0);

            user.setExternalId(lamsUser.getUserId());
            fetchGroups(user, lamsUser);
            fetchOrganisations(user, lamsUser);

            return true;
        }

        return false;
    }

    private void fetchGroups(User user, LamsUser lamsUser) {
        LamsUserGroupExample userGroupExample = new LamsUserGroupExample();
        userGroupExample.createCriteria().andGroupIdEqualTo(lamsUser.getUserId());
        List<LamsUserGroup> userGroups = userGroupMapper.selectByExample(userGroupExample);

        LamsGroupExample groupExample = new LamsGroupExample();
        for (LamsUserGroup userGroup : userGroups) {
            groupExample.or().andGroupIdEqualTo(userGroup.getGroupId());
        }

        List<LamsGroup> lamsGroups = groupMapper.selectByExample(groupExample);
        ArrayList<Group> groups = new ArrayList<Group>();
        for (LamsGroup lamsGroup : lamsGroups) {
            Group group = new Group();
            group.setExternalId(lamsGroup.getGroupId());
            group.setName(lamsGroup.getGroupName());
            groups.add(group);
        }
        user.setGroups(groups);
    }

    private void fetchOrganisations(User user, LamsUser lamsUser) {
        LamsUserOrganisationExample userOrganisationExample = new LamsUserOrganisationExample();
        userOrganisationExample.createCriteria().andUserIdEqualTo(lamsUser.getUserId());
        List<LamsUserOrganisation> userOrganisations =
                userOrganisationMapper.selectByExample(userOrganisationExample);

        LamsOrganisationExample organisationExample = new LamsOrganisationExample();
        for (LamsUserOrganisation userOrganisation : userOrganisations) {
            organisationExample.or().andOrganisationIdEqualTo(userOrganisation.getOrganisationId());
        }

        List<LamsOrganisation> lamsOrganisations = organisationMapper.selectByExample(organisationExample);
        ArrayList<Organisation> organisations = new ArrayList<Organisation>();
        for (LamsOrganisation lamsOrganisation : lamsOrganisations) {
            if(lamsOrganisation.getOrganisationStateId() == 1 /*ACTIVE*/) {
                Organisation organisation = new Organisation();
                organisation.setExternalId(lamsOrganisation.getOrganisationId());
                organisation.setName(lamsOrganisation.getName());
                organisation.setDescription(lamsOrganisation.getDescription());
                organisations.add(organisation);
            }
        }
        user.setOrganisations(organisations);
    }

}
